package com.jinke.api.modules.third.trackApi;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jinke.api.modules.third.trackApi.model.response.TrackVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author huang
 * @data 2024-06-06
 */
@Slf4j
public class TrackApiUtils {
    private static final String KEY = "E4564AFA5509112CA803150B75759A2F";
    private static final String REGISTER_URL = "https://api.17track.net/track/v2/register";
    /**
     * 获取详情 该接口每次可提交 40 个物流单号；
     */
    private static final String GETTRACKINFO_URL = "https://api.17track.net/track/v2/gettrackinfo";


    /**
     * 注册运单号
     * @param numbers
     * @return {"code":0,"data":{"accepted":[],"rejected":[{"number":"778093750740","error":{"code":-18019901,"message":"The tracking number '778093750740' has been registered, don't need to repeat registration."}}]}}
     * @return {"code":0,"data":{"accepted":[{"origin":3,"number":"778105034396","email":null,"lang":null,"carrier":100003}],"rejected":[]}}
     * @return  code=429 是因为接口并发为 每秒 3个请求
     */
    public static String register(List<String> numbers) {
        List<TrackApi> a = numbers.stream().map(s -> {
            TrackApi trackApi = new TrackApi();
            trackApi.setNumber(s);
            return trackApi;
        }).collect(Collectors.toList());
        String body = JSON.toJSONString(a);
        String out = "";
        try {
            log.info("------------TrackApi 运单号注册接口请求------------>" + body);
            out = sendPostRequest(REGISTER_URL, body);
            log.info("------------TrackApi 运单号注册接口响应------------>" + out);
            return out;
        } catch (Exception e) {
            log.info("------------TrackApi 运单号注册接口异常------------>out:" +out+"error:"+ e.getMessage());
        }
        return null;
    }

    /**
     * 获取详情
     * @param numbers
     * @return
     */
    public static String getTrackinfo(List<String> numbers) {
        List<TrackApi> a = numbers.stream().map(s -> {
            TrackApi trackApi = new TrackApi();
            trackApi.setNumber(s);
           // trackApi.setCarrier(s);
            return trackApi;
        }).collect(Collectors.toList());
        String body = JSON.toJSONString(a);
        String out = "";
        try {
            Thread.sleep(3000);
            log.info("TrackApi 获取详情接口参数------------{}", body);
            out = sendPostRequest(GETTRACKINFO_URL, body);
            log.info("TrackApi 获取详情接口响应------------>{}", out);
            return out;
        } catch (Exception e) {
            log.info("TrackApi 获取详情接口异常------------>out:{}, error:{}", out, e.getMessage());
        }
        return null;
    }

    /**
     * Post
     *
     * @param url  路径
     * @param body 请求体
     * @return 结果
     * @throws IOException io
     */
    public static String sendPostRequest(String url, String body) throws IOException {
        HttpURLConnection connection = null;
        try {
            // 创建连接
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 10809));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }
            connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("17token", KEY);
            connection.setDoOutput(true);

            // 写入请求体
            try (OutputStream outputStream = connection.getOutputStream()) {
                outputStream.write(body.getBytes("UTF-8"));
            }

            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
                // 获取错误消息体
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
                    StringBuilder errorResponse = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        errorResponse.append(line);
                    }
                    return errorResponse.toString();
                }
            } else {
                // 获取正常响应
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    return response.toString();
                }
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    public static void main(String[] args) {
        //本地没加入白名单请求只会401没返回
        List<String> numbers = new ArrayList<>();
        numbers.add("92055901255817500142056721");
        String register = register(numbers);
        System.out.println(register);
         /*List<String> numbers = Lists.newArrayList();
         numbers.add("92001901156017300251881963");
         numbers.add("1Z01Y30F0397497719");
         numbers.add("92001901156017300251907830");
         numbers.add("92001901156017300251927593");
         numbers.add("92001901156017300251923168");
         getTrackinfo(numbers);*/
    }

    /**
     * 根据返回补充订阅
     * @param rejected
     */
    public static void registerByResponds(JSONArray rejected) {
        Gson gson = new Gson();
        try {

            Type mapType = new TypeToken<List<TrackVO>>() {
            }.getType();

            List<TrackVO> trackVOList = gson.fromJson(rejected.toJSONString(), mapType);
            //运单号
            List<String> numberList = trackVOList.stream().map(TrackVO::getNumber).collect(Collectors.toList());
            //再次注册
            TrackApiUtils.register(numberList);

        } catch (Exception e) {
            log.info(e.getMessage()+"补充订阅");
        }
    }
}
